package com.xbongbong.pro.aiassistant.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.UserSimpPojo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.aiassistant.help.SsServiceHelp;
import com.xbongbong.pro.aiassistant.manager.feign.BusinessFeignClient;
import com.xbongbong.pro.aiassistant.service.SsDistributeSaveService;
import com.xbongbong.pro.constant.AiAssistantConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.AiAssistantEntity;
import com.xbongbong.pro.domain.entity.AiAssistantHistoryEntity;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.smartsettings.enums.AiAssistantPushTypeEnum;
import com.xbongbong.pro.enums.smartsettings.enums.SmartActionTypeEnum;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.rabbitmq.producer.AiAssistantBaseProducer;
import com.xbongbong.pro.service.toolbox.smartsettings.help.SmartSettingsHelp;
import com.xbongbong.pro.smartsettings.pojo.SmartFieldAttrPojo;
import com.xbongbong.pro.smartsettings.pojo.SmartStrategyPojo;
import com.xbongbong.pro.smartsettings.pojo.SsExecutorPojo;
import com.xbongbong.pro.smartsettings.pojo.SsHistoryValidPojo;
import com.xbongbong.pro.smartsettings.pojo.SsMessageMergePojo;
import com.xbongbong.pro.smartsettings.pojo.SsTimeAndExecutorPojo;
import com.xbongbong.pro.smartsettings.pojo.dto.SmartStrategyRabbitMqDTO;
import com.xbongbong.pro.sms.pojo.SmsReceiverPojo;
import com.xbongbong.pro.sms.pojo.dto.SmsRabbitMqDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.SmsSetConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CommunicatePlanUserEntity;
import com.xbongbong.saas.domain.entity.ext.CommunicatePlanEntityExt;
import com.xbongbong.saas.enums.SmsSendTypeEnum;
import com.xbongbong.saas.enums.SmsTemplateSendApiEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.BomBillEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.SupplierContactEnum;
import com.xbongbong.saas.enums.business.SupplierEnum;
import com.xbongbong.saas.model.AiAssistantHistoryModel;
import com.xbongbong.saas.model.CommunicatePlanModel;
import com.xbongbong.saas.model.CommunicatePlanUserModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;


/**
 * @description: 智能助手--数据分发&记录入库
 * @Author: hongxiao
 * @date: 2019-05-16 11:15
 * @since v1.0
 */
@Service("ssDistributeSaveService")
public class SsDistributeSaveServiceImpl implements SsDistributeSaveService {
    private static final Logger LOG = LoggerFactory.getLogger(SsDistributeSaveServiceImpl.class);

    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private CommunicatePlanModel communicatePlanModel;
    @Resource
    private CommunicatePlanUserModel communicatePlanUserModel;
    @Resource
    private AiAssistantHistoryModel aiAssistantHistoryModel;
    @Resource
    private SsServiceHelp ssServiceHelp;
    @Resource
    private BusinessFeignClient businessFeignClient;
    @Resource
    private AiAssistantBaseProducer aiAssistantBaseProducer;
    @Resource
    private SmartSettingsHelp smartSettingsHelp;


    @Override
    public void distributeAndSave(SmartStrategyRabbitMqDTO rabbitMqDTO, List<SsHistoryValidPojo> validHistoryList,
                                  Map<Integer, List<PaasFormDataEntityExt>> saasDataListMap, List<PaasFormDataEntityExt> paasDataList,
                                  List<SsMessageMergePojo> messageMergeList, List<SsExecutorPojo> executorList,
                                  Map<Long, SsExecutorPojo> workReportExecutorListMap, Map<Long, List<AiAssistantHistoryEntity>> workReportValidListMap,
                                  Boolean isTest, Map<Long, List<MessageRabbitMqDTO>> testMessageMap,
                                  Map<Long, List<Map<String, String>>> testCommunicatePlanMap,
                                  Map<Long, List<SmsReceiverPojo>> testSmsMap, boolean noSaveDistribution) throws XbbException {
        String corpid = rabbitMqDTO.getCorpid();
        // 分组：消息、执行人、记录数据
        Map<Long, List<SsMessageMergePojo>> messageMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        messageMergeList.forEach(item -> {
            Long smartId = item.getSmartSettingsId();
            if (messageMap.containsKey(smartId)) {
                messageMap.get(smartId).add(item);
            } else {
                List<SsMessageMergePojo> list = new ArrayList<>();
                list.add(item);
                messageMap.put(smartId, list);
            }
        });
        Map<Long, List<SsExecutorPojo>> executorMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        executorList.forEach(item -> {
            Long smartId = item.getSmartSettingsId();
            if (executorMap.containsKey(smartId)) {
                executorMap.get(smartId).add(item);
            } else {
                List<SsExecutorPojo> list = new ArrayList<>();
                list.add(item);
                executorMap.put(smartId, list);
            }
        });
        Map<Long, SsHistoryValidPojo> historyValidMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        validHistoryList.forEach(item -> {
            historyValidMap.put(item.getSmartSettingsId(), item);
        });


        List<AiAssistantEntity> smsSmartList = new ArrayList<>();
        List<AiAssistantEntity> workReportSmartList = new ArrayList<>();
        List<AiAssistantEntity> saasSmartList = new ArrayList<>();
        List<AiAssistantEntity> paasSmartList = new ArrayList<>();
        ssServiceHelp.getSmartSettingsForCategory(rabbitMqDTO.getList(), smsSmartList, workReportSmartList, saasSmartList, paasSmartList);

        // saas数据分发
        if (!saasSmartList.isEmpty()) {
            saasFormDataDistributeSave(corpid, saasSmartList, saasDataListMap, messageMap, executorMap, historyValidMap, isTest, testMessageMap,
                    testCommunicatePlanMap, noSaveDistribution);
        }
        // paas数据分发
        if (!paasSmartList.isEmpty()) {
            paasFormDataDistributeSave(corpid, paasSmartList, paasDataList, messageMap, executorMap, historyValidMap, isTest, testMessageMap, noSaveDistribution);
        }
        // 短信数据分发
        if (!smsSmartList.isEmpty()) {
            for (AiAssistantEntity entity : smsSmartList) {
                Long smartId = entity.getId();
                SsHistoryValidPojo historyValidPojo = historyValidMap.get(smartId);
                if (Objects.isNull(historyValidPojo)) {
                    continue;
                }
                List<Long> addUpdateIds = historyValidPojo.getAddAndUpdateIds();

                // 区分客户短信，还是paas短信
                List<PaasFormDataEntityExt> dataList = new ArrayList<>();
                if (Objects.equals(SaasMarkEnum.SAAS.getCode(), entity.getSaasMark())) {
                    List<PaasFormDataEntityExt> saasFormList = saasDataListMap.get(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                    dataList = getFormDataEntityList(addUpdateIds, saasFormList);
                } else if (Objects.equals(SaasMarkEnum.PAAS.getCode(), entity.getSaasMark())) {
                    dataList = getFormDataEntityList(addUpdateIds, paasDataList);
                }
                SmartStrategyPojo strategyPojo = entity.getStrategy().toJavaObject(SmartStrategyPojo.class);
                Integer triggerNum = strategyPojo.getStrategyNum();

                smsDistributeSave(dataList, historyValidPojo, corpid, triggerNum, entity, isTest, testSmsMap, noSaveDistribution);
            }
        }
        // 工作报告分发
        if (!workReportSmartList.isEmpty()) {
            // 工作报告只能发消息
            for (AiAssistantEntity entity : workReportSmartList) {
                Long smartId = entity.getId();
                // 执行人
                SsExecutorPojo executorPojo = workReportExecutorListMap.get(smartId);
                // 有效数据
                List<AiAssistantHistoryEntity> workReportValidList = workReportValidListMap.get(smartId);
                // 执行次数
                SmartStrategyPojo strategyPojo = entity.getStrategy().toJavaObject(SmartStrategyPojo.class);
                Integer triggerNum = strategyPojo.getStrategyNum();
                // 执行动作
                SmartActionTypeEnum actionTypeEnum = SmartActionTypeEnum.getByCode(entity.getAction());
                switch (actionTypeEnum) {
                    case MESSAGE:
                        // 走消息方法
                        workReportMessageDistributeSave(executorPojo, workReportValidList, corpid, triggerNum, entity, isTest, testMessageMap, noSaveDistribution);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    /**
     * saas数据分发--记录入库（消息、访客计划）
     *
     * @param corpid          公司id
     * @param saasSmartList   saas智能助手
     * @param saasDataListMap saas业务数据{businessType:[dataEntityExt1,dataEntityExt2]}
     * @param messageMap      消息执行人对应的数据{smartId:[messageMergePojo1,messageMergePojo2]}
     * @param executorMap     执行人{smartId:[executorPojo1,executorPojo2]}
     * @param historyValidMap 入库的数据{smartId:[historyValidPojo1,historyValidPojo2]}
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-13 15:17
     * @version v1.0
     * @since v1.0
     */
    private void saasFormDataDistributeSave(String corpid, List<AiAssistantEntity> saasSmartList, Map<Integer, List<PaasFormDataEntityExt>> saasDataListMap,
                                            Map<Long, List<SsMessageMergePojo>> messageMap, Map<Long, List<SsExecutorPojo>> executorMap,
                                            Map<Long, SsHistoryValidPojo> historyValidMap, Boolean isTest, Map<Long, List<MessageRabbitMqDTO>> testMessageMap,
                                            Map<Long, List<Map<String, String>>> testCommunicatePlanMap, boolean noSaveDistribution) throws XbbException {
        for (AiAssistantEntity entity : saasSmartList) {
            Long smartId = entity.getId();
            // 分发的消息
            List<SsMessageMergePojo> messageList = messageMap.get(smartId);
            // 访客的执行人
            List<SsExecutorPojo> executorPojoList = executorMap.get(smartId);
            Map<Long, SsExecutorPojo> executorPojoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (Objects.nonNull(executorPojoList) && !executorPojoList.isEmpty()) {
                executorPojoList.forEach(item -> {
                    executorPojoMap.put(item.getDataId(), item);
                });
            }
            // 记录入库
            SsHistoryValidPojo historyValidPojo = historyValidMap.get(smartId);
            if (Objects.isNull(historyValidPojo)) {
                continue;
            }
            // 分发的数据
            List<Long> addUpdateIds = historyValidPojo.getAddAndUpdateIds();
            // 源数据
            List<PaasFormDataEntityExt> formDataList = saasDataListMap.get(entity.getBusinessType());
            // formId对应的数据
            List<PaasFormDataEntityExt> dataList = getFormDataEntityList(addUpdateIds, formDataList);

            // 执行次数
            SmartStrategyPojo strategyPojo = entity.getStrategy().toJavaObject(SmartStrategyPojo.class);
            Integer triggerNum = strategyPojo.getStrategyNum();
            // 执行动作
            SmartActionTypeEnum actionTypeEnum = SmartActionTypeEnum.getByCode(entity.getAction());
            switch (actionTypeEnum) {
                case MESSAGE:
                    // 走消息方法
                    messageDistributeSave(executorPojoMap, messageList, historyValidPojo, corpid, triggerNum, entity, dataList, isTest, testMessageMap, noSaveDistribution);
                    break;
                case ADD_COMMUNICATE_PLAN:
                    communicatePlanDistributeSave(executorPojoMap, dataList, historyValidPojo, corpid, triggerNum, entity, testCommunicatePlanMap, noSaveDistribution);
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * paas数据分发--记录入库（消息）
     *
     * @param corpid          公司id
     * @param paasSmartList   paas智能助手
     * @param messageMap      消息执行人对应的数据{smartId:[messageMergePojo1,messageMergePojo2]}
     * @param executorMap     执行人{smartId:[executorPojo1,executorPojo2]}
     * @param historyValidMap 入库的数据{smartId:[historyValidPojo1,historyValidPojo2]}
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-13 15:24
     * @version v1.0
     * @since v1.0
     */
    private void paasFormDataDistributeSave(String corpid, List<AiAssistantEntity> paasSmartList, List<PaasFormDataEntityExt> paasDataList,
                                            Map<Long, List<SsMessageMergePojo>> messageMap, Map<Long, List<SsExecutorPojo>> executorMap,
                                            Map<Long, SsHistoryValidPojo> historyValidMap, Boolean isTest, Map<Long, List<MessageRabbitMqDTO>> testMessageMap,
                                            boolean noSaveDistribution) throws XbbException {
        // TODO 目前只有发送短信和消息，此方法只处理消息，短信已在短信分发方法处理
        for (AiAssistantEntity entity : paasSmartList) {
            Long smartId = entity.getId();
            // 分发的消息
            List<SsMessageMergePojo> messageList = messageMap.get(smartId);
            // 访客的执行人
            List<SsExecutorPojo> executorPojoList = executorMap.get(smartId);
            Map<Long, SsExecutorPojo> executorPojoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            executorPojoList.forEach(item -> {
                executorPojoMap.put(item.getDataId(), item);
            });
            // 记录入库
            SsHistoryValidPojo historyValidPojo = historyValidMap.get(smartId);
            // 执行次数
            Integer triggerNum = entity.getStrategy().toJavaObject(SmartStrategyPojo.class).getStrategyNum();
            // 执行动作
            SmartActionTypeEnum actionTypeEnum = SmartActionTypeEnum.getByCode(entity.getAction());
            switch (actionTypeEnum) {
                case MESSAGE:
                    // 走消息方法
                    messageDistributeSave(executorPojoMap, messageList, historyValidPojo, corpid, triggerNum, entity, paasDataList, isTest, testMessageMap, noSaveDistribution);
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 消息分发--记录入库
     *
     * @param messageMergeList 消息执行人
     * @param historyValidPojo 记录数据
     * @param triggerNum       执行次数
     * @param entity           智能助手实体
     * @param dataList         数据id列表
     * @param isTest           是否为测试
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-05-17 14:00
     * @version v1.0
     * @since v1.0
     */
    private void messageDistributeSave(Map<Long, SsExecutorPojo> executorPojoMap, List<SsMessageMergePojo> messageMergeList,
                                       SsHistoryValidPojo historyValidPojo, String corpid, Integer triggerNum, AiAssistantEntity entity,
                                       List<PaasFormDataEntityExt> dataList, Boolean isTest, Map<Long, List<MessageRabbitMqDTO>> testMessageMap,
                                       boolean noSaveDistribution) throws XbbException {

        if (Objects.isNull(messageMergeList)) {
            messageMergeList = new ArrayList<>();
        }

        // 发送时间
        String sendTimeStr = getStrategyTime(entity);
        Long sendTime = DateTimeUtil.getInt(sendTimeStr, DateTimeUtil.SDFYMDHM);
        // 测试不填，默认为当前时间
        if (isTest) {
            sendTime = null;
        }
        String nameAttr = getNameAttr(entity.getBusinessType());
        // 产品库存预警、四个待跳转用到pushType
        AiAssistantPushTypeEnum pushTypeEnum = smartSettingsHelp.otherPush(entity);
        // 产品消息
        boolean isProductFlag = Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(), entity.getBusinessType());
        if (isProductFlag) {
            // 推送到库存查询：产品库存上限预警、产品库存下限预警、产品保质期预警
            if (Objects.isNull(pushTypeEnum)) {
                productMessageDistributeSave(executorPojoMap, messageMergeList, historyValidPojo, corpid, triggerNum, entity, dataList, sendTime, isTest, testMessageMap, noSaveDistribution);
            } else {
                productStockMessageDistributeSave(executorPojoMap, messageMergeList, historyValidPojo, corpid, triggerNum, entity, dataList, sendTime, isTest, testMessageMap, pushTypeEnum, noSaveDistribution);
            }
            return;
        }

        // title内容
        String title = XbbRefTypeEnum.AI_ASSISTANT.getName() + PaasConstant.COLON + entity.getName();
        // 占位符的修改
        String placeHolder = smartSettingsHelp.getPlaceHolder(SaasMarkEnum.SAAS.getCode(), entity.getBusinessType());

        // 客户，机会的subBusinessType需要做特殊处理
        Integer subBusinessType = entity.getBusinessType();
        if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), subBusinessType)) {
            subBusinessType = XbbRefTypeEnum.CUSTOMER.getCode();
        } else if (Objects.equals(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), subBusinessType)) {
            subBusinessType = XbbRefTypeEnum.ALL_OPPORTUNITY.getCode();
        } else if (Objects.equals(XbbRefTypeEnum.CLUE.getCode(), subBusinessType)) {
            subBusinessType = XbbRefTypeEnum.ALL_CLUE.getCode();
        } else if (Objects.nonNull(pushTypeEnum)) {
            subBusinessType = pushTypeEnum.getSubCode();
        }

        // 其他消息
        for (SsMessageMergePojo item : messageMergeList) {

            if (item.getDataIdList().size() > AiAssistantConstant.MAX_DATAID_LENGTH) {
                // 记录数据
                continue;
            }

            // 占位符替换
            String content = handleContentPlaceholder(entity.getMemo(), placeHolder, item.getDataIdList().size(), nameAttr);
            // 测试时使用
            if (isTest) {
                content = content + DateUtil.getString();
            }

            PushRefTypePojo.Options options = new PushRefTypePojo.Options(entity.getAppId(), entity.getMenuId(),
                    entity.getFormId(), null, item.getDataIdList(), entity.getSaasMark(),
                    entity.getBusinessType(), subBusinessType);

            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(item.getExcutorId()), item.getDataIdList(), 0,
                    sendTime, title, content, null, options);

            // 四个待推送有类型
            if (Objects.isNull(pushTypeEnum)) {
                pushTypeEnum = AiAssistantPushTypeEnum.getPushTypeBySubCode(entity.getBusinessType());
            } else {

            }
            if (Objects.equals(AiAssistantPushTypeEnum.UNKNOWN, pushTypeEnum)) {
                return;
            }
            try {
                // 分发数据
                if (!noSaveDistribution) {
                    aiAssistantBaseProducer.sendMessage(pushTypeEnum, messageRabbitMqDTO);
                }

                // 测试回显使用
                List<MessageRabbitMqDTO> list = testMessageMap.getOrDefault(entity.getId(), new ArrayList<>());
                list.add(messageRabbitMqDTO);
                testMessageMap.put(entity.getId(), list);
            } catch (XbbException e) {
                throw e;
            }
        }
        // 入库
        if (!noSaveDistribution) {
            messageDataSave(corpid, executorPojoMap, historyValidPojo, triggerNum);
        }
    }

    /**
     * 产品消息分发--记录入库
     *
     * @param executorPojoMap  执行人
     * @param messageMergeList 消息聚合列表
     * @param historyValidPojo 有效记录
     * @param corpid           公司id
     * @param triggerNum       执行次数
     * @param entity           智能助手实体
     * @param dataList         数据id列表
     * @param sendTime         执行时间
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-12-03 15:03
     * @version v1.0
     * @since v1.0
     */
    private void productMessageDistributeSave(Map<Long, SsExecutorPojo> executorPojoMap, List<SsMessageMergePojo> messageMergeList,
                                              SsHistoryValidPojo historyValidPojo, String corpid, Integer triggerNum, AiAssistantEntity entity,
                                              List<PaasFormDataEntityExt> dataList, Long sendTime, Boolean isTest,
                                              Map<Long, List<MessageRabbitMqDTO>> testMessageMap, boolean noSaveDistribution) throws XbbException {

        Map<Long, Long> productMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        List<Long> parentIdList = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : dataList) {
            if (!Objects.equals(entity.getFormId(), entityExt.getFormId())) {
                continue;
            }
            JSONObject data = entityExt.getData();
            Long parentId = data.getLong(ProductEnum.PARENT_ID.getAttr());
            if (Objects.equals(parentId, 0L)) {
                parentIdList.add(entityExt.getId());
                continue;
            }
            productMap.put(entityExt.getId(), parentId);
        }

        // title内容
        String title = XbbRefTypeEnum.AI_ASSISTANT.getName() + PaasConstant.COLON + entity.getName();
        // 占位符的修改
        String placeHolder = smartSettingsHelp.getPlaceHolder(SaasMarkEnum.SAAS.getCode(), entity.getBusinessType());

        // 添加消息
        for (SsMessageMergePojo item : messageMergeList) {

            Set<Long> parentIdSet = new HashSet<>();
            for (Long productId : item.getDataIdList()) {
                if (productMap.containsKey(productId)) {
                    parentIdSet.add(productMap.get(productId));
                }
            }

            if (parentIdSet.size() > AiAssistantConstant.MAX_DATAID_LENGTH || parentIdSet.isEmpty()) {
                // 记录数据
                continue;
            }

            List<Long> productIdList = new ArrayList<>(parentIdSet);


            // 占位符替换
            String content = handleContentPlaceholder(entity.getMemo(), placeHolder, productIdList.size(), ProductEnum.NAME.getAttr());
            // 测试时使用
            if (isTest) {
                content = content + DateUtil.getString();
            }
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(entity.getAppId(), entity.getMenuId(),
                    entity.getFormId(), null, productIdList, entity.getSaasMark(),
                    entity.getBusinessType(), entity.getBusinessType());

            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(item.getExcutorId()), productIdList, 0,
                    sendTime, title, content, null, options);

            // paas怎么推送
            AiAssistantPushTypeEnum pushTypeEnum = AiAssistantPushTypeEnum.getPushTypeBySubCode(entity.getBusinessType());
            if (Objects.equals(AiAssistantPushTypeEnum.UNKNOWN, pushTypeEnum)) {
                return;
            }
            try {
                // 分发数据
                if (!noSaveDistribution) {
                    aiAssistantBaseProducer.sendMessage(pushTypeEnum, messageRabbitMqDTO);
                }

                // 测试回显使用
                List<MessageRabbitMqDTO> list = testMessageMap.getOrDefault(entity.getId(), new ArrayList<>());
                list.add(messageRabbitMqDTO);
                testMessageMap.put(entity.getId(), list);
            } catch (XbbException e) {
                throw e;
            }
        }
        // 不入库
        if (noSaveDistribution) {
            return;
        }

        // 过虑子产品数据
        if (Objects.nonNull(historyValidPojo.getAddList()) && !historyValidPojo.getAddList().isEmpty()) {
            historyValidPojo.getAddList().removeIf(historyEntity -> !parentIdList.contains(historyEntity.getDataId()));
        }
        if (Objects.nonNull(historyValidPojo.getUpdateList()) && !historyValidPojo.getUpdateList().isEmpty()) {
            historyValidPojo.getUpdateList().removeIf(historyEntity -> !parentIdList.contains(historyEntity.getDataId()));
        }


        messageDataSave(corpid, executorPojoMap, historyValidPojo, triggerNum);
    }

    /**
     * 库存查询消息--记录入库
     *
     * @param executorPojoMap  执行人
     * @param messageMergeList 消息聚合列表
     * @param historyValidPojo 有效记录
     * @param corpid           公司id
     * @param triggerNum       执行次数
     * @param entity           智能助手实体
     * @param dataList         数据id列表
     * @param sendTime         执行时间
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-12-03 20:04
     * @version v1.0
     * @since v1.0
     */
    private void productStockMessageDistributeSave(Map<Long, SsExecutorPojo> executorPojoMap, List<SsMessageMergePojo> messageMergeList,
                                                   SsHistoryValidPojo historyValidPojo, String corpid, Integer triggerNum, AiAssistantEntity entity,
                                                   List<PaasFormDataEntityExt> dataList, Long sendTime, Boolean isTest,
                                                   Map<Long, List<MessageRabbitMqDTO>> testMessageMap, AiAssistantPushTypeEnum pushTypeEnum,
                                                   boolean noSaveDistribution) throws XbbException {

        Integer businessType = entity.getBusinessType();
        Integer subBusinessType = XbbRefTypeEnum.STOCK_SEARCH.getCode();

        // title内容
        String title = XbbRefTypeEnum.AI_ASSISTANT.getName() + PaasConstant.COLON + entity.getName();
        // 占位符的修改
        String placeHolder = smartSettingsHelp.getPlaceHolder(SaasMarkEnum.SAAS.getCode(), entity.getBusinessType());

        List<Long> childProductIdList = new ArrayList<>();
        for (PaasFormDataEntityExt dataEntityExt : dataList) {
            if (!Objects.equals(entity.getFormId(), dataEntityExt.getFormId())) {
                continue;
            }
            JSONObject data = dataEntityExt.getData();
            Long parentId = data.getLong(ProductEnum.PARENT_ID.getAttr());
            if (Objects.equals(parentId, 0L)) {
                continue;
            }
            childProductIdList.add(dataEntityExt.getId());
        }
        // 添加消息
        for (SsMessageMergePojo item : messageMergeList) {

            item.getDataIdList().retainAll(childProductIdList);

            if (item.getDataIdList().size() > AiAssistantConstant.MAX_DATAID_LENGTH || item.getDataIdList().isEmpty()) {
                // 记录数据
                continue;
            }

            // 占位符替换
            String content = handleContentPlaceholder(entity.getMemo(), placeHolder, item.getDataIdList().size(), ProductEnum.NAME.getAttr());
            // 测试时使用
            if (isTest) {
                content = content + DateUtil.getString();
            }
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(entity.getAppId(), entity.getMenuId(),
                    entity.getFormId(), null, item.getDataIdList(), entity.getSaasMark(),
                    businessType, subBusinessType);

            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(item.getExcutorId()), item.getDataIdList(), 0,
                    sendTime, title, content, null, options);

            if (Objects.isNull(pushTypeEnum)) {
                return;
            }

            try {
                if (!noSaveDistribution) {
                    aiAssistantBaseProducer.sendMessage(pushTypeEnum, messageRabbitMqDTO);
                }

                // 测试回显使用
                List<MessageRabbitMqDTO> list = testMessageMap.getOrDefault(entity.getId(), new ArrayList<>());
                list.add(messageRabbitMqDTO);
                testMessageMap.put(entity.getId(), list);
            } catch (XbbException e) {
                throw e;
            }
        }
        if (noSaveDistribution) {
            return;
        }

        // 过虑父产品数据
        if (Objects.nonNull(historyValidPojo.getAddList()) && !historyValidPojo.getAddList().isEmpty()) {
            historyValidPojo.getAddList().removeIf(historyEntity -> !childProductIdList.contains(historyEntity.getDataId()));
        }
        if (Objects.nonNull(historyValidPojo.getUpdateList()) && !historyValidPojo.getUpdateList().isEmpty()) {
            historyValidPojo.getUpdateList().removeIf(historyEntity -> !childProductIdList.contains(historyEntity.getDataId()));
        }

        messageDataSave(corpid, executorPojoMap, historyValidPojo, triggerNum);
    }

    /**
     * 工作报告消息分发--记录入库
     *
     * @param executorPojo        消息执行人
     * @param workReportValidList 有效记录数据
     * @param corpid              公司id
     * @param triggerNum          执行次数
     * @param entity              智能助手实体
     * @param isTest              是否测试
     * @param testMessageMap      回显的测试数据
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-13 16:24
     * @version v1.0
     * @since v1.0
     */
    private void workReportMessageDistributeSave(SsExecutorPojo executorPojo, List<AiAssistantHistoryEntity> workReportValidList,
                                                 String corpid, Integer triggerNum, AiAssistantEntity entity,
                                                 Boolean isTest, Map<Long, List<MessageRabbitMqDTO>> testMessageMap, boolean noSaveDistribution) throws XbbException {
        // 判断是日报，周报，月报

        // 发送时间
        String sendTimeStr = getStrategyTime(entity);
        Long sendTime = DateTimeUtil.getInt(sendTimeStr, DateTimeUtil.SDFYMDHM);
        // 测试不填，默认为当前时间
        if (isTest) {
            sendTime = null;
        }
        List<UserEntity> userList = null;
        if (Objects.nonNull(executorPojo)) {
            userList = executorPojo.getExecutorList();
        }

        if (Objects.nonNull(userList) && !userList.isEmpty()) {
            // 添加消息
            for (UserEntity userEntity : userList) {
                String title = XbbRefTypeEnum.AI_ASSISTANT.getName() + PaasConstant.COLON + entity.getName();
                // 占位符的修改
                String placeHolder = smartSettingsHelp.getPlaceHolder(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_REPORT.getCode());
                // content内容
                String content = entity.getMemo();
                content = content.replaceAll("\\{" + placeHolder + "\\}", "");
                // 测试时使用
                if (isTest) {
                    content = content + DateUtil.getString();
                }

                PushRefTypePojo.Options options = new PushRefTypePojo.Options(entity.getAppId(), entity.getMenuId(), entity.getFormId(),
                        0L, Collections.singletonList(0L), entity.getSaasMark(), XbbRefTypeEnum.WORK_REPORT.getCode(), XbbRefTypeEnum.WORK_REPORT.getCode());

                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(userEntity.getUserId()), Collections.singletonList(0L), 0,
                        sendTime, title, content, null, options);
                try {
                    if (!noSaveDistribution) {
                        aiAssistantBaseProducer.sendMessage(AiAssistantPushTypeEnum.WORK_REPORT_PUSH, messageRabbitMqDTO);
                    }

                    // 测试回显使用
                    List<MessageRabbitMqDTO> list = testMessageMap.getOrDefault(entity.getId(), new ArrayList<>());
                    list.add(messageRabbitMqDTO);
                    testMessageMap.put(entity.getId(), list);
                } catch (XbbException e) {
                    throw e;
                }
            }
        }

        // 消息入库
        if (!noSaveDistribution) {
            workReportMessageDataSave(corpid, entity, userList, workReportValidList, triggerNum);
        }
    }

    /**
     * 短信分发--记录入库
     *
     * @param formDataList     业务数据
     * @param historyValidPojo 记录数据
     * @param triggerNum       执行次数
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-05-17 15:35
     * @version v1.0
     * @since v1.0
     */
    private void smsDistributeSave(List<PaasFormDataEntityExt> formDataList, SsHistoryValidPojo historyValidPojo,
                                   String corpid, Integer triggerNum, AiAssistantEntity entity, Boolean isTest,
                                   Map<Long, List<SmsReceiverPojo>> testSmsMap, boolean noSaveDistribution) throws XbbException {
        // saas只有客户可以发送短信，paas发送短信的字段为：单行文本&&手机类型
        Integer saasMark = entity.getSaasMark();

        // 电话map：{dataId:mobile}，名称map:{dataId:name}
        Map<Long, String> mobileMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, String> nameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<SmsReceiverPojo> receiverPojoList = new ArrayList<>();
        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            // 只有有电话的客户可以发送短信
            formDataList.forEach(item -> {
                JSONObject dataList = item.getData();
                String mobile = getCustomerFirstMobile(dataList);
                String name = dataList.getString(CustomerManagementEnum.NAME.getAttr());
                if (Objects.nonNull(mobile)) {
                    mobileMap.put(item.getId(), mobile);
                    nameMap.put(item.getId(), name);

                    SmsReceiverPojo pojo = new SmsReceiverPojo(name, mobile);
                    receiverPojoList.add(pojo);
                }
            });
        } else if (Objects.equals(SaasMarkEnum.PAAS.getCode(), saasMark)) {
            JSONArray smsExecutorList = entity.getSmsExecutor();
            if (Objects.isNull(smsExecutorList) || smsExecutorList.isEmpty()) {
                return;
            }
            // 当前只取第一个字段，TODO 以后可扩展成手机多个字段
            SmartFieldAttrPojo executorAttr = smsExecutorList.getObject(0, SmartFieldAttrPojo.class);
            formDataList.forEach(item -> {
                JSONObject dataList = item.getData();
                String mobile = dataList.getString(executorAttr.getAttr());
                // TODO 标题是个列表，怎么玩；为了取到paas标题这个小小的数据，前期要准备好对应的表单、解释，不划算；还是使用mobile作为标题吧
//                List<FormTitlePoJo> formTitleList = ExplainUtil.getFormTitle(JSONArray.parseArray(paasFormEntityExt.getCustomTitle()), explainMap, dataList, explainList, item);
//                StringBuilder title = new StringBuilder();
//                for (FormTitlePoJo titlePoJo : formTitleList) {
//                    title.append(titlePoJo.getContent());
//                    for (Object object : titlePoJo.getValue()) {
//                        title.append(object.toString());
//                    }
//                }
//                String name = title.toString();
//                name = name.isEmpty() ? mobile : name;

                if (Objects.nonNull(mobile)) {

                    mobileMap.put(item.getId(), mobile);
                    nameMap.put(item.getId(), mobile);

                    SmsReceiverPojo pojo = new SmsReceiverPojo(mobile, mobile);
                    receiverPojoList.add(pojo);
                }
            });
        }


        String sendTime = getStrategyTime(entity);

        String placeholder = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getName();
        String content = entity.getMemo();
        if (content.contains("{" + placeholder + "}")) {
            content = content.replaceAll("\\{" + placeholder + "\\}", I18nMessageUtil.getMessage(SmsSetConstant.SMS_RECEIVER_PLACE_HOLDER));
        }

        try {
            SmsRabbitMqDTO smsRabbitMqDTO = new SmsRabbitMqDTO();
            smsRabbitMqDTO.setCorpid(corpid);
            // 系统生成
            smsRabbitMqDTO.setUserId(PaasConstant.SYS_USER_ID);
            if (isTest) {
                smsRabbitMqDTO.setSendType(SmsSendTypeEnum.AT_ONCE.getCode());
            } else {
                smsRabbitMqDTO.setSendType(SmsSendTypeEnum.DELAY.getCode());
            }
            // 短信发送API类型
            smsRabbitMqDTO.setSendApi(SmsTemplateSendApiEnum.SPACE_IMAGINATION_NOTICE_AMOUNT.getCode());
            // 尊称无法传递，直接替换
            smsRabbitMqDTO.setContent(content);
            smsRabbitMqDTO.setDates(sendTime);
            smsRabbitMqDTO.setSendData(receiverPojoList);
            Locale locale = LocaleContextHolder.getLocale();
            String lang = locale.toString();
            if (!noSaveDistribution) {
                String sendData = businessFeignClient.smsSend(smsRabbitMqDTO, lang);
                JSONObject resultObj = JsonHelperUtil.parseObject(sendData);
                if (ErrorCodeEnum.API_SUCCESS.getCode() != (int) resultObj.get(StringConstant.CODE)) {
                    throw new XbbException(resultObj.getIntValue(StringConstant.CODE), resultObj.getString(StringConstant.KEY_ERROR_MSG));
                }
            }

            // 测试回显使用
            testSmsMap.put(entity.getId(), receiverPojoList);
        } catch (XbbException e) {
            throw e;
        }

        // 不入库数据
        if (noSaveDistribution) {
            return;
        }

        // 添加记录
        List<AiAssistantHistoryEntity> allAddList = historyValidPojo.getAddList();
        if (allAddList != null && allAddList.size() > 0) {
            List<AiAssistantHistoryEntity> addList = new ArrayList<>();
            for (AiAssistantHistoryEntity historyEntity : allAddList) {
                Long dataId = historyEntity.getDataId();
                if (nameMap.containsKey(dataId)) {
                    AiAssistantHistoryEntity aiAssistantHistoryEntity = new AiAssistantHistoryEntity();
                    BeanUtil.copyProperties(historyEntity, aiAssistantHistoryEntity);
                    // 执行人
                    UserEntity cusUser = new UserEntity();
                    cusUser.setUserId(dataId.toString());
                    cusUser.setName(nameMap.get(dataId));
                    addTimeAndExecutor(aiAssistantHistoryEntity, Collections.singletonList(cusUser), triggerNum);
                    addList.add(aiAssistantHistoryEntity);
                }

            }
            // 批量添加记录
            aiAssistantHistoryModel.insertBatch(addList);
        }

        // 更新
        List<AiAssistantHistoryEntity> allUpdateList = historyValidPojo.getUpdateList();
        if (allUpdateList != null && allUpdateList.size() > 0) {
            List<AiAssistantHistoryEntity> updateList = new ArrayList<>();
            for (AiAssistantHistoryEntity historyEntity : allUpdateList) {
                Long dataId = historyEntity.getDataId();
                AiAssistantHistoryEntity aiAssistantHistoryEntity = new AiAssistantHistoryEntity();
                BeanUtil.copyProperties(historyEntity, aiAssistantHistoryEntity);
                // 执行人
                UserEntity cusUser = new UserEntity();
                cusUser.setUserId(dataId.toString());
                cusUser.setName(nameMap.get(dataId));
                addTimeAndExecutor(aiAssistantHistoryEntity, Collections.singletonList(cusUser), triggerNum);
                updateList.add(aiAssistantHistoryEntity);
            }
            // 批量更新记录
            aiAssistantHistoryModel.updateBatch(updateList, corpid);
        }

        // 失效记录
        invalidBatch(corpid, historyValidPojo.getInvalidIdsList());
    }

    /**
     * 新增访客--记录入库
     *
     * @param formDataList     业务数据
     * @param historyValidPojo 记录数据
     * @param corpid           公司id
     * @param triggerNum       执行次数
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-05-17 15:36
     * @version v1.0
     * @since v1.0
     */
    private void communicatePlanDistributeSave(Map<Long, SsExecutorPojo> executorPojoMap, List<PaasFormDataEntityExt> formDataList,
                                               SsHistoryValidPojo historyValidPojo, String corpid, Integer triggerNum, AiAssistantEntity entity,
                                               Map<Long, List<Map<String, String>>> testCommunicatePlanMap, boolean noSaveDistribution) throws XbbException {

        // 不入库数据
        if (noSaveDistribution) {
            return;
        }
        // 执行记录
        Map<Long, AiAssistantHistoryEntity> addHistoryMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, AiAssistantHistoryEntity> updateHistoryMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        historyValidPojo.getAddList().forEach(item -> {
            addHistoryMap.put(item.getDataId(), item);
        });
        historyValidPojo.getUpdateList().forEach(item -> {
            updateHistoryMap.put(item.getDataId(), item);
        });

        // 发送时间
        String sendTimeStr = getStrategyTime(entity);
        Long sendTime = DateTimeUtil.getInt(sendTimeStr, DateTimeUtil.SDFYMDHM);


        PaasFormEntityExt paasFormEntity = paasFormModel.getByBusinessType(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), corpid);
        for (PaasFormDataEntityExt customer : formDataList) {
            // 客户id
            Long customerId = customer.getId();

            // 执行人
            SsExecutorPojo pojo = executorPojoMap.get(customerId);
            List<UserEntity> userEntitys = pojo.getExecutorList();

            JSONObject communicatePlan = new JSONObject();
            JSONObject customerData = customer.getData();
            String customerName = customerData.getString(CustomerManagementEnum.NAME.getAttr());
            // 访客计划名称
            String name = customerName + I18nMessageUtil.getMessage(I18nStringConstant.COMMUNICATE_PLAN) + PaasConstant.LEFT_BRACKET + I18nMessageUtil.getMessage(AiAssistantConstant.AI_ASSISTANT_GENERATE) + PaasConstant.RIGHT_BRACKET;
            communicatePlan.put(CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), customerId);
            communicatePlan.put(CommunicatePlanEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), customerName);
            communicatePlan.put(CommunicatePlanEnum.NAME.getAttr(), name);
            communicatePlan.put(CommunicatePlanEnum.MEMO.getAttr(), I18nMessageUtil.getMessage(AiAssistantConstant.AI_ASSISTANT_GENERATE_MEMO));
            try {
                List<String> executorTypeList = Arrays.asList("2");
                communicatePlan.put(CommunicatePlanEnum.EXECUTOR.getAttr(), executorTypeList);
                communicatePlan.put(CommunicatePlanEnum.NOTIFY_TYPE.getAttr(), "0");
                // 访客计划执行时间
                communicatePlan.put(CommunicatePlanEnum.COMMUNICATE_TIME.getAttr(), sendTime);
                // 访客计划备注以及名称
                CommunicatePlanEntityExt communicatePlanEntityExt = new CommunicatePlanEntityExt();
                BeanUtil.copyProperties(paasFormEntity, communicatePlanEntityExt);
                communicatePlanEntityExt.setFormId(paasFormEntity.getId());
                communicatePlanEntityExt.setData(communicatePlan);
                communicatePlanEntityExt.setDel(BasicConstant.ZERO);
                communicatePlanEntityExt.setId(null);
                communicatePlanEntityExt.setFlowStatus(FlowStatusEnum.NOT_NEED_APPROVAL.getType());
                // 创建人
                communicatePlanEntityExt.setCreatorId(PaasConstant.SYS_USER_ID);
                // 负责人
                communicatePlanEntityExt.setOwnerId(PaasConstant.SYS_USER_ID);
                communicatePlanEntityExt.setSerialNo("");
                communicatePlanEntityExt.setDepartmentId(0L);
                communicatePlanModel.insert(communicatePlanEntityExt);

                // 保存执行人
                List<UserSimpPojo> executorUserList = new ArrayList<>();
                List<CommunicatePlanUserEntity> planUserList = new ArrayList<>();
                for (UserEntity user : userEntitys) {
                    CommunicatePlanUserEntity planUser = new CommunicatePlanUserEntity();
                    planUser.setCorpid(corpid);
                    planUser.setDataId(communicatePlanEntityExt.getId());
                    planUser.setUserId(user.getUserId());
                    planUser.setUserName(user.getName());
                    planUser.setUserAvatar(user.getAvatar());
                    planUser.setIsCreator(BasicConstant.ZERO);
                    planUserList.add(planUser);

                    UserSimpPojo userSimpPojo = new UserSimpPojo();
                    userSimpPojo.setUserId(user.getUserId());
                    userSimpPojo.setName(user.getName());
                    executorUserList.add(userSimpPojo);
                }
                communicatePlanUserModel.insertBatch(planUserList);

                // 保存记录
                long now = DateUtil.getInt();
                AiAssistantHistoryEntity historyEntity;
                // 执行人&执行时间
                SsTimeAndExecutorPojo timeAndExecutorPojo = new SsTimeAndExecutorPojo();
                timeAndExecutorPojo.setTime(now);
                timeAndExecutorPojo.setUsers(executorUserList);
                JSONArray timeAndExecutorArray;
                if (updateHistoryMap.containsKey(customerId)) {
                    historyEntity = updateHistoryMap.get(customerId);
                } else {
                    historyEntity = addHistoryMap.get(customerId);
                    historyEntity.setAddTime(now);
                }
                historyEntity.setUpdateTime(now);
                timeAndExecutorArray = historyEntity.getTimeAndExecutor();
                if (Objects.isNull(timeAndExecutorArray)) {
                    timeAndExecutorArray = new JSONArray();
                }
                timeAndExecutorArray.add(timeAndExecutorPojo);
                historyEntity.setTimeAndExecutor(timeAndExecutorArray);

                // 执行次数是否失效
                Integer invalidFlag = timeAndExecutorArray.size() >= triggerNum ? BasicConstant.ONE : BasicConstant.ZERO;
                historyEntity.setTriggerInvalid(invalidFlag);
                aiAssistantHistoryModel.save(historyEntity);

                // 测试回显使用
                Map<String, String> communicatePlanMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                StringBuffer executorNameBuffer = new StringBuffer();
                for (UserSimpPojo userSimpPojo : executorUserList) {
                    if (executorNameBuffer.length() == BasicConstant.ZERO) {
                        executorNameBuffer.append(userSimpPojo.getName());
                    } else {
                        executorNameBuffer.append("、" + userSimpPojo.getName());
                    }
                }
                communicatePlanMap.put(customerName + StringConstant.CROSS + customerId, executorNameBuffer.toString());
                List<Map<String, String>> testList = testCommunicatePlanMap.getOrDefault(entity.getId(), new ArrayList<>());
                testList.add(communicatePlanMap);
                testCommunicatePlanMap.put(entity.getId(), testList);

            } catch (Exception e) {
                // 报错
                throw e;
            }
        }

        // 批量失效
        invalidBatch(corpid, historyValidPojo.getInvalidIdsList());
    }

    /**
     * 获取客户第一个手机号
     *
     * @param dataList 业务数据
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-05-17 17:09
     * @version v1.0
     * @since v1.0
     */
    @Override
    public String getCustomerFirstMobile(JSONObject dataList) {
        JSONArray phoneJsonArray;
        String cusPhone = dataList.getString(CustomerManagementEnum.PHONE.getAttr());
        try {
            phoneJsonArray = JSONArray.parseArray(cusPhone);
        } catch (Exception e) {
            phoneJsonArray = new JSONArray();
        }
        if (phoneJsonArray.size() > 0) {
            for (int i = 0; i < phoneJsonArray.size(); i++) {
                String tel = (String) phoneJsonArray.getJSONObject(i).get("text_2");
                if (StringUtil.isMobile(tel)) {
                    return tel;
                }
            }
        }
        return null;
    }

    /**
     * 批量失效
     *
     * @param corpid      公司id
     * @param invalidList 失效记录
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-05-23 22:27
     * @version v1.0
     * @since v1.0
     */
    private void invalidBatch(String corpid, List<Long> invalidList) {
        if (Objects.nonNull(invalidList) && !invalidList.isEmpty()) {

            List<Long> allDataIdList = new ArrayList<>(invalidList);
            int count = allDataIdList.size();
            int start = 0;
            int pageNum = 2000;
            for (; start <= count; start = start + pageNum) {
                // 分组数据的endIndex
                int endIndex = (start + pageNum) <= count ? start + pageNum : count;
                List<Long> dataIds = allDataIdList.subList(start, endIndex);
                aiAssistantHistoryModel.invalidBatch(corpid, dataIds);
            }
        }
    }

    /**
     * 添加执行人&记录是否失效
     *
     * @param entity     记录实体
     * @param userList   执行人
     * @param triggerNum 执行次数
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-05-23 22:26
     * @version v1.0
     * @since v1.0
     */
    private void addTimeAndExecutor(AiAssistantHistoryEntity entity, List<UserEntity> userList, Integer triggerNum) {
        List<UserSimpPojo> userSimpPojoList = new ArrayList<>();
        userList.forEach(item -> {
            UserSimpPojo pojo = new UserSimpPojo();
            pojo.setName(item.getName());
            pojo.setUserId(item.getUserId());
            pojo.setUserAvatar(item.getAvatar());
            userSimpPojoList.add(pojo);
        });

        long now = DateUtil.getInt();

        SsTimeAndExecutorPojo timeAndExecutorPojo = new SsTimeAndExecutorPojo();
        timeAndExecutorPojo.setTime(now);
        timeAndExecutorPojo.setUsers(userSimpPojoList);


        JSONArray timeAndExecutorArray = entity.getTimeAndExecutor();
        if (Objects.isNull(timeAndExecutorArray)) {
            timeAndExecutorArray = new JSONArray();
        }
        timeAndExecutorArray.add(timeAndExecutorPojo);
        entity.setTimeAndExecutor(timeAndExecutorArray);
        // 执行次数是否失效
        triggerNum = triggerNum == null ? BasicConstant.ONE : triggerNum;
        Integer invalidFlag = timeAndExecutorArray.size() >= triggerNum ? BasicConstant.ONE : BasicConstant.ZERO;
        entity.setTriggerInvalid(invalidFlag);
        entity.setTriggerNum(timeAndExecutorArray.size());
        entity.setUpdateTime(now);
    }


    /**
     * 获取要分发的数据
     *
     * @param addUpdateIds       需要添加更新的数据ids
     * @param sourceFormDataList 业务源数据
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-13 15:09
     * @version v1.0
     * @since v1.0
     */
    private List<PaasFormDataEntityExt> getFormDataEntityList(List<Long> addUpdateIds, List<PaasFormDataEntityExt> sourceFormDataList) {

        if (Objects.isNull(sourceFormDataList) || sourceFormDataList.isEmpty()) {
            return new ArrayList<>();
        }

        List<PaasFormDataEntityExt> dataList = new ArrayList<>();
        sourceFormDataList.forEach(item -> {
            if (addUpdateIds.contains(item.getId())) {
                dataList.add(item);
            }
        });

        return dataList;
    }

    /**
     * 获取智能助手执行时间
     *
     * @param * @param null
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-11-12 21:18
     * @version
     * @since
     */
    private String getStrategyTime(AiAssistantEntity entity) {
        // 执行时间
        SmartStrategyPojo strategy = JSONObject.toJavaObject(entity.getStrategy(), SmartStrategyPojo.class);
        // 时分
        String timeStr = strategy.getStrategyTime();
        // 发送时间
        String sendTime = DateTimeUtil.getString(DateTimeUtil.SDFDate) + " " + timeStr;
        return sendTime;
    }

    /**
     * 获取名称attr
     *
     * @param businessType 业务类型
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-12-03 14:35
     * @version v1.0
     * @since v1.0
     */
    @Override
    public String getNameAttr(Integer businessType) {
        XbbRefTypeEnum refTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        String attr = "";
        switch (refTypeEnum) {
            case CUSTOMER_MANAGEMENT:
                attr = CustomerManagementEnum.NAME.getAttr();
                break;
            case CONTACT:
                attr = ContractEnum.NAME.getAttr();
                break;
            case SALES_OPPORTUNITY:
                attr = SalesOpportunityEnum.NAME.getAttr();
                break;
            case CONTRACT:
                attr = ContractEnum.NAME.getAttr();
                break;
            case REFUND:
                attr = RefundEnum.REFUND_NAME.getAttr();
                break;
            case QUOTATION:
                attr = QuotationEnum.NAME.getAttr();
                break;
            case SUPPLIER:
                attr = SupplierEnum.SUPPLIER_NAME.getAttr();
                break;
            case SUPPLIER_CONTACT:
                attr = SupplierContactEnum.NAME.getAttr();
                break;
            case PURCHASE:
                attr = PurchaseEnum.PURCHASE_NAME.getAttr();
                break;
            case BOM_BILL:
                attr = BomBillEnum.NAME.getAttr();
                break;
            case PRODUCT:
                attr = ProductEnum.NAME.getAttr();
                break;
            default:
                break;
        }

        return attr;
    }


    /**
     * 消息记录入库
     *
     * @param corpid           公司id
     * @param executorPojoMap  执行人
     * @param historyValidPojo 有效数据
     * @param triggerNum       执行次数
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-12-03 20:35
     * @version v1.0
     * @since v1.0
     */
    private void messageDataSave(String corpid, Map<Long, SsExecutorPojo> executorPojoMap, SsHistoryValidPojo historyValidPojo, Integer triggerNum) throws XbbException {
        List<AiAssistantHistoryEntity> addList = historyValidPojo.getAddList();
        if (Objects.nonNull(addList) && !addList.isEmpty()) {
            Iterator<AiAssistantHistoryEntity> it = addList.iterator();
            while (it.hasNext()) {
                AiAssistantHistoryEntity historyEntity = it.next();
                SsExecutorPojo executorPojo = executorPojoMap.get(historyEntity.getDataId());
                if (Objects.isNull(executorPojo)) {
                    it.remove();
                } else {
                    addTimeAndExecutor(historyEntity, executorPojo.getExecutorList(), triggerNum);
                }
            }
            // 批量添加记录
            if (!addList.isEmpty()) {
                int count = addList.size();
                int start = 0;
                int pageNum = 1000;
                for (; start <= count; start = start + pageNum) {
                    // 分组数据的endIndex
                    int endIndex = (start + pageNum) <= count ? start + pageNum : count;
                    List<AiAssistantHistoryEntity> subAddList = addList.subList(start, endIndex);
                    if (!subAddList.isEmpty()) {
                        aiAssistantHistoryModel.insertBatch(subAddList);
                    }
                }
            }
        }
        // 更新
        List<Long> invalidIdsList = historyValidPojo.getInvalidIdsList();
        if (Objects.isNull(invalidIdsList)) {
            invalidIdsList = new ArrayList<>();
        }
        List<AiAssistantHistoryEntity> updateList = historyValidPojo.getUpdateList();
        if (Objects.nonNull(updateList) && !updateList.isEmpty()) {
            Iterator<AiAssistantHistoryEntity> it = updateList.iterator();
            while (it.hasNext()) {
                AiAssistantHistoryEntity historyEntity = it.next();
                SsExecutorPojo executorPojo = executorPojoMap.get(historyEntity.getDataId());
                if (Objects.isNull(executorPojo)) {
                    invalidIdsList.add(historyEntity.getId());
                    it.remove();
                } else {
                    addTimeAndExecutor(historyEntity, executorPojo.getExecutorList(), triggerNum);
                }
            }
            // 批量更新记录
            if (!updateList.isEmpty()) {
                int count = updateList.size();
                int start = 0;
                int pageNum = 1000;
                for (; start <= count; start = start + pageNum) {
                    // 分组数据的endIndex
                    int endIndex = (start + pageNum) <= count ? start + pageNum : count;
                    List<AiAssistantHistoryEntity> subUpdateList = updateList.subList(start, endIndex);
                    if (!subUpdateList.isEmpty()) {
                        aiAssistantHistoryModel.updateBatch(subUpdateList, corpid);
                    }
                }
            }
        }

        // 失效
        invalidBatch(corpid, historyValidPojo.getInvalidIdsList());
    }

    /**
     * 工作报告消息数据入库
     *
     * @param corpid              公司id
     * @param entity              智能助手实体
     * @param executorList        执行人列表
     * @param workReportValidList 上次有效入库记录
     * @param triggerNum          执行次数
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-12-25 22:15
     * @version
     * @since
     */
    private void workReportMessageDataSave(String corpid, AiAssistantEntity entity, List<UserEntity> executorList,
                                           List<AiAssistantHistoryEntity> workReportValidList, Integer triggerNum) throws XbbException {

        if (Objects.isNull(executorList) || executorList.isEmpty()) {
            // 执行人为空，失效
            if (Objects.isNull(workReportValidList) || workReportValidList.isEmpty()) {
                return;
            }
            List<Long> inValidIdList = new ArrayList<>();
            for (AiAssistantHistoryEntity historyEntity : workReportValidList) {
                inValidIdList.add(historyEntity.getId());
            }
            invalidBatch(corpid, inValidIdList);
            return;
        }

        if (Objects.isNull(workReportValidList) || workReportValidList.isEmpty()) {
            // 添加
            AiAssistantHistoryEntity historyEntity = new AiAssistantHistoryEntity();
            BeanUtil.copyProperties(entity, historyEntity);
            historyEntity.setId(null);
            historyEntity.setDataId(null);
            historyEntity.setAiAssistantId(entity.getId());
            addTimeAndExecutor(historyEntity, executorList, triggerNum);

            aiAssistantHistoryModel.insert(historyEntity);

        } else {
            // 更新
            for (AiAssistantHistoryEntity historyEntity : workReportValidList) {
                addTimeAndExecutor(historyEntity, executorList, triggerNum);
            }
            aiAssistantHistoryModel.updateBatch(workReportValidList, corpid);
        }
    }

    /**
     * 占位符替换
     *
     * @param content     内容
     * @param placeHolder 占位符
     * @param size        数量
     * @param nameAttr    名称attr
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-12-03 20:44
     * @version v1.0
     * @since v1.0
     */
    @Override
    public String handleContentPlaceholder(String content, String placeHolder, Integer size, String nameAttr) {
//        // 只有一个数据显示名称或编号，多个数据显示数量
//        String really;
//        if (size > 1) {
//            really = PaasConstant.LEFT_BRACKET + size + PaasConstant.RIGHT_BRACKET;
//        } else {
//            JSONObject data = entityExt.getData();
//            String name = data.getString(nameAttr);
//            name = Objects.isNull(name) ? "" : name;
//            String serialNo = Objects.isNull(entityExt.getSerialNo()) ? "" : entityExt.getSerialNo();
//            really = PaasConstant.LEFT_BRACKET + name + StringConstant.UNDER_LINE + serialNo + PaasConstant.RIGHT_BRACKET;
//        }
//        return content.replaceAll("\\{" + placeHolder + "\\}", really);

        return content.replaceAll("\\{" + placeHolder + "\\}", "");
    }
}
